package com.elitesland.core.config.argument.resolver;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.read.metadata.holder.ReadRowHolder;
import com.elitesland.core.util.excel.support.ExcelColumnCheckUtil;
import com.elitesland.model.ExcelImportVO;
import com.google.gson.Gson;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * 直接用map接收数据
 *
 * @author niuchen
 */
public class ExcelDataListener extends AnalysisEventListener<Map<Integer, String>> {
    private static final Logger LOGGER = LoggerFactory.getLogger(ExcelDataListener.class);
    /**
     * 每隔5条存储数据库，实际使用中可以3000条，然后清理list ，方便内存回收
     */
    private static final int BATCH_COUNT = 5;
    // List<Map<Integer, String>> list = new ArrayList<Map<Integer, String>>();
    private ExcelImportVO excelImportVO = new ExcelImportVO();
    private  List<String> errMsgList = excelImportVO.getErrMsgList();
    private  List<Map<Integer, Object>> dataMapsList = excelImportVO.getDataMapsList();

    public Optional<ExcelImportVO> getExcelImportVO(){
        return Optional.of(excelImportVO);
    }
    /**
     * 这里会一行行的返回头
     *
     * @param headMap
     * @param context
     */
    @Override
    public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
        LOGGER.info("invokeHeadMap 解析到一条头数据:{}", new Gson().toJson(headMap));
         ReadRowHolder readRowHolder = context.readRowHolder();
        int rowindex = readRowHolder.getRowIndex();

        if (rowindex == 0) {
            //     RowTypeEnum rowType = readRowHolder.getRowType();
            if(StringUtils.isBlank(headMap.get(1))){

            }
            excelImportVO.setTableName(headMap.get(1));
        } else if (rowindex == 1) {
            if(StringUtils.isBlank(headMap.get(1))){

            }
            excelImportVO.setType(headMap.get(1));
        }
        excelImportVO.getHeadMapList().add(headMap);
    }

//    private final static String columnType[] = new String[]{"INTEGER", "VARCHAR", "TINYINT"};
//
//    private boolean ColumnTypeCheck(String s) {
//        if (StringUtils.isBlank(s)) {
//            return false;
//        }
//        boolean check = false;
//        for (String st : columnType) {
//            if (!st.startsWith(s)) {
//                check = true;
//                break;
//            }
//        }
//        return check;
//    }

    @Override
    public void invoke(Map<Integer, String> data, AnalysisContext context) {
        LOGGER.info("invoke 解析到一条数据:{}", new Gson().toJson(data));
        ReadRowHolder readRowHolder = context.readRowHolder();
        int rowindex = readRowHolder.getRowIndex();
        Map<Integer, String> headMap1 = excelImportVO.getHeadMapList().get(0);//第一行字段类型
        Map<Integer, String> headMap3 = excelImportVO.getHeadMapList().get(3);//第四行是否必填

        HashMap<Integer, Object> hashMap = new HashMap();
        data.forEach((integer, value) -> {
            String columnType = headMap1.get(integer);
            String columnMust = headMap3.get(integer);
            if(columnType==null){
                hashMap.put(integer, value);
            }else if (columnType.startsWith("VARCHAR")) {
                if (checkBank(value,columnMust,rowindex,integer,hashMap)) {
                    if (!ExcelColumnCheckUtil.CheckStringlength(value, columnType)) {
                        errMsgList.add(getErrString(rowindex, integer, "长度超过限制.", value));
                    } else {
                        hashMap.put(integer, value);
                    }
                }
            } else if (columnType.startsWith("INTEGER") || columnType.startsWith("TINYINT")) {
                if (checkBank(value,columnMust,rowindex,integer,hashMap)) {
                    if (!ExcelColumnCheckUtil.CheckIntegerLength(value, columnType)) {
                        errMsgList.add(getErrString(rowindex, integer, "数据类型或长度错误.", value));
                    } else {
                        hashMap.put(integer, Integer.valueOf(value));
                    }
                }
            } else if (columnType.startsWith("NUMERIC")) {
                 if (checkBank(value,columnMust,rowindex,integer,hashMap)) {
                    if (!ExcelColumnCheckUtil.CheckFloatLength(value, columnType)) {
                        errMsgList.add(getErrString(rowindex, integer, "数据类型或长度错误.", value));
                    } else {
                        hashMap.put(integer, Float.valueOf(value));
                    }
                }
            } else if (columnType.startsWith("DATETIME")) {
                if ( checkBank(value,columnMust,rowindex,integer,hashMap)) {
                    if (!ExcelColumnCheckUtil.checkDateTime(value, columnType)) {
                        errMsgList.add(getErrString(rowindex, integer, "数据类型错误.", value));
                    }else{
                        hashMap.put(integer, value);
                    }
                }
            } else {
                hashMap.put(integer, value);
            }
        });

        dataMapsList.add(hashMap);


//        if (list.size() >= BATCH_COUNT) {
//            saveData();
//            list.clear();
//        }
    }
    private   boolean checkBank(String value, String columnMust, Integer rowindex, Integer integer, HashMap<Integer, Object> hashMap) {
        boolean columnMustBo;
        if (columnMust == null || !"*".equals(columnMust)) {
            columnMustBo = true;//可以空
        } else {
            columnMustBo = false;//不可空
        }
        if (StringUtils.isBlank(value) && !columnMustBo) {
            errMsgList.add(getErrString(rowindex, integer, "数据不可为空.", value));
            return false;
        } else if (StringUtils.isBlank(value) && columnMustBo) {
            hashMap.put(integer, null);
            return false;
        }else{
            return true;
        }
    }


    private String getErrString(int rowindex, Integer integer, String msg, String value) {
        Map<Integer, String> headMap1 = excelImportVO.getHeadMapList().get(0);//第一行字段类型
        Map<Integer, String> headMap3 = excelImportVO.getHeadMapList().get(2);//第四行是否必填
        StringBuffer stringBuffer = new StringBuffer();
        stringBuffer.append("第").append(rowindex).append("行->第").append(integer).append("列->")
                .append(headMap1.get(integer)).append(headMap3.get(integer)).append("->")
                .append(msg).append("值:").append(value);
        return stringBuffer.toString();
    }


    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        // saveData();
        // LOGGER.info("doAfterAllAnalysed 所有数据解析完成！");
    }


}
